// XXX should be renamed to dxdiag.h

#include <windows.h>
#include <commctrl.h>
#include <dxdiag.h>
#include <tchar.h>
#include <sys/stat.h>
#include <stdio.h>

#define BUF_SIZE 256

typedef struct _XML_Node
{
    LPWSTR tag;
    LPWSTR content;
    struct _XML_Node* child; /* *First* child in node tree */
    struct _XML_Node* sibling;
} XML_Node;

XML_Node* XML_initializeNode(LPCWSTR tag, LPCWSTR content);
XML_Node* XML_insertChildNode(XML_Node* node, LPCWSTR tag, LPCWSTR content);
XML_Node* XML_appendSiblingNode(XML_Node* node, LPCWSTR tag, LPCWSTR content);
void XML_freeTree(XML_Node* node);
void XML_parseTree(XML_Node* root, FILE* filp);

typedef struct
{
    IDxDiagProvider* prov;
    IDxDiagContainer* root;
} DxDiagCOM;

HRESULT DxDiagCOM_Init(DxDiagCOM* com);
HRESULT DxDiagCOM_GetContainer(IDxDiagContainer* source, LPCWSTR query, IDxDiagContainer** result);
HRESULT DxDiagCOM_GetProperty(IDxDiagContainer* source, LPCWSTR name, VARIANT* result);

BOOL DxDiagCOM_GetStringProperty(IDxDiagContainer* source, LPCWSTR query, LPWSTR* result);
BOOL DxDiagCOM_GetBoolProperty(IDxDiagContainer* source, LPCWSTR query, BOOL* result);
BOOL DxDiagCOM_GetIntegerProperty(IDxDiagContainer* source, LPCWSTR query, int* result);
BOOL DxDiagCOM_GetDwordProperty(IDxDiagContainer* source, LPCWSTR query, DWORD* result);

typedef struct
{
    /* Device info */
    LPWSTR      name;
    LPWSTR      hardwareID;
    LPWSTR      manufacturerID;
    LPWSTR      productID;
    LPWSTR      type;
    
    /* Driver info */
    LPWSTR      filename;
    LPWSTR      version;
    LPWSTR      attributes;
    LPWSTR      date;
    LPWSTR      otherFiles;
    LPWSTR      provider;
    LPWSTR      notes;
    int         whql;
} SoundInfo;

BOOL SoundInfo_GetInfo(DxDiagCOM* pcom, SoundInfo* info);
HRESULT DSoundTest_test(DWORD* tests,HWND hWnd);

extern SoundInfo soundInfo;
extern HWND hTabDisplay;

LRESULT CALLBACK Sound_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void Sound_DisplayData();

void Sound_SaveText(FILE* pFile);
void Sound_SaveXML(XML_Node* root);

typedef struct
{
    LPWSTR name;
    LPWSTR manufacturer;
    LPWSTR chipType;
    LPWSTR DACType;
    LPWSTR keyID;
    LPWSTR memory;
    LPWSTR displayMode;
    LPWSTR monitor;
    LPWSTR maxResolution;
    LPWSTR identifier;
} DeviceInfo;

typedef struct
{
    LPWSTR filename;
    LPWSTR version;
    LPWSTR language;
    LPWSTR ddiVersion;
    LPWSTR attributes;
    LPWSTR date;
    LPWSTR vdd;
    LPWSTR minivdd;
    LPWSTR minivddDate;
    LPWSTR vendorID;
    LPWSTR deviceID;
    LPWSTR subsystemID;
    LPWSTR revisionID;
} DriverInfo;

typedef struct
{
    DeviceInfo device;
    DriverInfo driver;
    LPWSTR     notes;
} DisplayInfo;

BOOL DisplayInfo_GetInfo(DxDiagCOM* pcom, DisplayInfo* info);

extern HWND hTabDisplay;
extern DisplayInfo displayInfo;

LRESULT CALLBACK Display_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void D3DTest_testD3D();
void DDrawTest_testDDraw();
void Display_DisplayData();
void Display_SaveText(FILE* pFile);
void Display_SaveXML(XML_Node* root);

typedef struct
{
    LPWSTR      description;
    LPWSTR      isSoftware;
    LPWSTR      kernelMode;
    LPWSTR      inout;
    LPWSTR      supportsDLS;
    LPWSTR      external;
    LPWSTR      defaultPort;
} PortInfo;

typedef struct
{
    PortInfo*   ports;
    UINT        numPorts;
    LPWSTR      dlsFilePath;
    LPWSTR      notes;
} MusicInfo;

BOOL MusicInfo_GetInfo(DxDiagCOM* pcom, MusicInfo* info);
LPWSTR BoolToChoice(BOOL input, LPCWSTR cTrue, LPCWSTR cFalse);
LPWSTR MusicInfo_BoolToYesNo(BOOL input);

extern HWND hTabDisplay;
extern MusicInfo musicInfo;

LRESULT CALLBACK Music_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void Music_DisplayData();

void Music_SaveText(FILE* pFile);
void Music_SaveXML(XML_Node* root);

typedef struct
{
    LPWSTR      name;
    LPWSTR      version;
    LPWSTR      attributes;
    LPWSTR      language;
    LPWSTR      date;
    LPWSTR      sizeStr;
    int         size;
} FileInfo;

typedef struct
{
    FileInfo*   files;
    LPWSTR      notes;
    UINT        numFiles;
} FilesInfo;

BOOL FilesInfo_GetInfo(DxDiagCOM* pcom, FilesInfo* info);

extern FilesInfo filesInfo;
extern HWND hTabDisplay;

LRESULT CALLBACK Files_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void Files_DisplayData();

void Files_SaveText(FILE* pFile);
void Files_SaveXML(XML_Node* node);

typedef struct
{
    LPWSTR      time;
    LPWSTR      timeLocalized;
    LPWSTR      machineName;
    LPWSTR      operatingSystem;
    LPWSTR      operatingSystemLong;
    LPWSTR      languages;
    LPWSTR      systemManufacturer;
    LPWSTR      systemModel;
    LPWSTR      bios;
    LPWSTR      processor;
    LPWSTR      physicalMemory;
    LPWSTR      pageFile;
    LPWSTR      windowsDirectory;
    LPWSTR      directxVersion;
    LPWSTR      directxSetup;
} SystemInfo;

BOOL SystemInfo_GetInfo(DxDiagCOM* pcom, SystemInfo* info);

extern SystemInfo systemInfo;
extern HWND hTabDisplay;

LRESULT CALLBACK System_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void System_DisplayData();

void System_SaveText(FILE* pFile);
void System_SaveXML(XML_Node* root);

typedef struct
{
    LPWSTR              fileName;
    LPWSTR              time;
    LONG                fileSize;
} DriverFileInfo;

typedef struct
{
    LPWSTR              deviceName;
    BOOL                isAttached;
    LPWSTR              ffDriver;
    DWORD               controllerID;
    DWORD               vendorID;
    DWORD               productID;
} DIDeviceInfo;

typedef struct
{
    LPWSTR              deviceName;
    LPWSTR              upperFilters;
    LPWSTR              serviceName;
    LPWSTR              deviceID;
    DWORD               vendorID;
    DWORD               productID;
    DWORD               numOfDriverFiles;
    DriverFileInfo*     driverFiles;
} InputDeviceInfo;

typedef struct
{
    DWORD               numOfDIDevices;
    DWORD               numOfPS2Devices;
    DWORD               numOfGameDevices;
    DWORD               numOfUSBDevices;
    BOOL                pollInterrupt;
    DIDeviceInfo*       DIDInfo;
    InputDeviceInfo*    PS2Info;
    InputDeviceInfo*    USBInfo;
    InputDeviceInfo*    GameportInfo;
    LPWSTR              notes;
} InputInfo;

BOOL InputInfo_GetInfo(DxDiagCOM* pcom, InputInfo* info);
void InputInfo_SaveDataText(FILE* pFile);

extern InputInfo inputInfo;
extern HWND hTabDisplay;

LRESULT CALLBACK Input_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void Input_DisplayData();

void Input_SaveText(FILE* pFile);
void Input_SaveXML(XML_Node* root);

typedef struct
{
    LPWSTR name;
    LPWSTR registry;
    LPWSTR file;
    LPWSTR version;
} DPlaySPInfo;

typedef struct
{
    LPWSTR name;
    LPWSTR registry;
    LPWSTR file;
    LPWSTR version;
    LPWSTR guid;
} DPlayAppInfo;

typedef struct
{
    DPlaySPInfo *sps;
    unsigned numSPs;
    DPlayAppInfo *apps;
    unsigned numApps;
    LPWSTR notes;
} NetworkInfo;

BOOL NetworkInfo_GetInfo(DxDiagCOM* pcom, NetworkInfo* info);

extern HWND hTabDisplay;
extern NetworkInfo networkInfo;

LRESULT CALLBACK Network_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void Network_DisplayData();
void Network_SaveText(FILE* pFile);
void Network_SaveXML(XML_Node* root);

WCHAR *DxDiag_LoadString(UINT id);
